//
// Created by Finchen on 2025/8/13.
//

#ifndef BEAMQUALITYANALYSIS_H
#define BEAMQUALITYANALYSIS_H

#include <QObject>
#include <QVector>
#include <QDebug>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <QDateTime>
#include"../BeamQuality/BeamQualityTypes.h"



// 定义圆周率常量（当系统未定义M_PI时）
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

// 测量模式枚举
enum class BeamQualityMeasurementMode {
    SemiAutomatic,      // 半自动：根据输入点位测量
    Automatic    // 全自动：扫描+拟合+测量
};

class BeamQualityAnalysis : public QObject {
    Q_OBJECT

public:
    explicit BeamQualityAnalysis(QObject* parent = nullptr);


    BeamFittingParams performBeamQualityFitting(const QVector<double>& positions,
                                                const QVector<double>& beamWidths,
                                                double wavelength = 940e-6);

    QVector<double> generateMeasurementPositions(const BeamFittingParams& paramsX,
                                                const BeamFittingParams& paramsY,
                                                const ScanConfiguration& scanConfig);

    QVector<ScanDataPoint> filterScanData(const QVector<ScanDataPoint>& rawData);

    void setWavelength(double wavelength);
    BeamQualityMeasurementResults calculateFullResults(const QVector<ScanDataPoint>& scanData,
                                                      const ScanConfiguration& config);

signals:

    void analysisStarted();
    void analysisProgress(int percentage);
    void analysisCompleted();
    void analysisError(const QString& error);

private:

    QVector<double> gaussNewtonLagrange(const QVector<double>& x, const QVector<double>& y,
                                       int maxIter = 100, double tolerance = 1e-6);

    // double calculateRayleighLength(const QVector<double>& positions,
    //                               const QVector<double>& beamWidths,
    //                               double waistPosition);
    //
    // void findBeamWaist(const QVector<double>& positions,
    //                   const QVector<double>& beamWidths,
    //                   double& waistPosition, double& waistRadius);


    QVector<double> calculateOptimalPositions(double z0, double zr, double zf);

    bool validateFittingResults(const BeamFittingParams& params);

    // bool validateScanData(const QVector<ScanDataPoint>& data);

    double calculateM2Factor(double w0, double zr, double wavelength, double discriminant);

    double calculateBPP(double wavelength, double m2);

    void findMinBeamWidthAndPosition(const QVector<double>& positions,
                                   const QVector<double>& beamWidths,
                                   double& minWidth, double& correspondingPosition);

    double m_wavelength=940e-6;



};

#endif //BEAMQUALITYANALYSIS_H
